﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;

namespace WinnerCMS.Data
{
    public class EFRepository<T> : IRepository<T> where T : class,new()
    {
        readonly Entities _context;
        public EFRepository(Entities context)
        {
            this._context = context;
        }


        public T Create()
        {
            return this._context.Set<T>().Create();
        }

        public T Update(T entity)
        {
            this._context.Entry<T>(entity).State = EntityState.Modified;
            this._context.SaveChangesAsync().Wait();
            return entity;
        }

        public T Insert(T entity)
        {
            this._context.Set<T>().Add(entity);
            this._context.SaveChangesAsync().Wait();
            return entity;
        }

        public void Delete(object id)
        {
            var t = this._context.Set<T>().Find(id);
            Delete(t);
        }

        public void Delete(T entity)
        {
            this._context.Set<T>().Remove(entity);
            this._context.SaveChangesAsync().Wait();
        }

        public T Find(params object[] keyValues)
        {
            return this._context.Set<T>().Find(keyValues);
        }

        public IList<T> FindAll()
        {
            return this._context.Set<T>().AsNoTracking().ToList<T>();
        }

        public IList<T> FindAll(Func<T, object> orderKey, int pageSize, int pageIndex)
        {
            return this._context.Set<T>().AsNoTracking().OrderBy(orderKey).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList<T>();
        }

        public IList<T> FindAll(Func<T, bool> predicate)
        {
            return this._context.Set<T>().AsNoTracking().Where<T>(predicate).ToList<T>();
        }

        public IList<T> FindAll(Func<T, bool> predicate, Func<T, object> orderKey, int pageSize, int pageIndex)
        {
            return this._context.Set<T>().AsNoTracking().Where<T>(predicate).OrderBy(orderKey).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList<T>();
        }

        public IList<T> FindBySql(string sql, params object[] parameters)
        {
            return this._context.Set<T>().SqlQuery(sql, parameters).ToList<T>();
        }


        public int Sum(Func<T, int> selector)
        {
            return this._context.Set<T>().Sum(selector);
        }

        public int Count(Func<T, bool> predicate)
        {
            return this._context.Set<T>().Count(predicate);
        }

        public TResult Max<TResult>(Func<T, TResult> selector)
        {
            return this._context.Set<T>().Max(selector);
        }

        public TResult Min<TResult>(Func<T, TResult> selector)
        {
            return this._context.Set<T>().Min(selector);
        }
    }
}